#include <stdio.h>
#include <ctype.h>
#include <string.h>

#define KEY 6
char *keyword[KEY] = {"for", "if", "then", "else", "while", "do"};
char id[1024];
int idcnt = 0 ; 
int num;
int token;
int expect(FILE *fp , int a,int b){
	char x = getc(fp) ; 
	if(x >= a && x <= b) {
		return x ; 
	}
	else {
		if(x != ' ' || x != '\t' || x != '\n') ungetc(x , fp) ; 
		return -1 ; 
	}
}
int expectword(FILE * fp){
	while(1){
		char x = getc(fp) ; 
		if(x >= '0' && x <= '9' || x >= 'a' && x <= 'z' || x >= 'A' && x <= 'Z'){
			id[idcnt ++] = x ; 
		}
		else {
			if(x != ' ' || x != '\t' || x != '\n') ungetc(x , fp) ;
			id[idcnt ++] = 0 ; 
			break ; 
		}
	}
	for(int i=0;i<6;i++){
		if(strstr(keyword[i] , id) != NULL && strstr(id , keyword[i]) != NULL){
			return i+1 ; 
		}
	}
	return 0 ; 
}
void getback(char x , FILE* fp){
	if(x != ' ' || x != '\t' || x != '\n') ungetc(x , fp) ;
}
void lexical(FILE *fp) {
        char x = getc(fp);
        num = 0;
        memset(id , 0, sizeof(id)) ; 
        strcpy(id, "\0");
        idcnt =0 ; 
        
        id[idcnt++] = x ; 
        
		if(x == EOF) {
			token = 0 ; return  ; 
		}
		if(x >= '0' && x <= '9') { 
			num = x - '0' ; 
			while(1){
				char k = expect(fp , '0' , '9') ; 
				if(k == -1) break ;
				num *= 10 ; 
				num += k - '0' ; 
			}
			token = 11 ; 
			return ; 
		}
		else if(x >= 'a' && x <= 'z' || x >= 'A' && x <= 'Z'){
			int res = expectword(fp); 
			if(res == 1) {
				token = res ; 
			}
			else token = 10 ; 
			return ; 
		}
		else if(x == '=') {
			token = 25 ; return ; 
		}
		else if(x == '+') {
			token = 13;return;
		}
		else if(x == '-') {
			token = 14;return;
		}
		else if(x == '*') {
			token = 15;return;
		}
		else if(x == '/') {
			token = 16;return;
		}
		else if(x == ';') {
			token = 26;return;
		}
		else if(x == '(') {
			token = 27;return;
		}
		else if(x == ')') {
			token = 28;return;
		}
		else if(x == '#') {
			token = 0;return;
		}
		else if(x == ':'){
			x = getc(fp) ; 
			if(x == '=') {
				id[idcnt ++] = x ; token = 18 ; return ; 
			}
			else{
				getback(x , fp) ; token = 17 ; return  ; 
			}
		}
		else if(x == '<'){
			x = getc(fp) ; 
			if(x == '=') {
				id[idcnt ++] = x ; token = 22 ; return ; 
			}
			else if(x == '>') {
				id[idcnt ++] = x ; token = 21 ; return ; 
			}
			else{
				getback(x , fp) ; token = 20 ; return  ; 
			}
		}
		else if(x == '>'){
			x = getc(fp) ; 
			if(x == '=') {
				id[idcnt ++] = x ; token = 24 ; return ; 
			}
			else{
				getback(x,fp) ; token = 23 ; return  ; 
			}
		}
		else {
			token = 100 ; 
		}
        //process x
        //process each regex here
        //store the result in global variables id, num, or token
        //in case of backtrack, use
        //ungetc(x, fp);

}

int main(int argc, const char *argv[])
{
        if(argc < 2) {
                printf("insufficient args\n");
                return 1;
        }
        FILE *fp = fopen(argv[1] , "r");
        do {
                lexical(fp);
                switch(token) {
                        case 10: printf("(id, %s)\n", id); break;
                        case 11: printf("(num, %d)\n", num); break;
                        case -1: printf("error!\n"); break;
                        case 100: break ; 
                        default: printf("(%d, %s)\n", token, id);
                }
        } while(token != 0);


        fclose(fp);
        return 0;
}

